#!/usr/bin/env python
# author: aaloy


import logging
log = logging.getLogger(__name__)

from django.core.paginator import Paginator,  InvalidPage, EmptyPage


class JPaginator(object):
    "This is a helper class to match jqgrid library"
    def __init__(self, request, query, num_rows=25):
        self.request = request
        self.rta = {}
        self.rows={}
        self.query = query
        self.num_rows = num_rows
        
    def jqfilter(self, op,field,value):
        """We need to make the conversion from the search parameters that
        jqgrid sends and the sql ones.
        I you send a non existing codintion it would apply the equal one"""

        identity = lambda x:x
        f_list = lambda x: x.split(',')
        django_equivalences = {
                  'eq': ('filter', '%s__iexact', identity),
                  'ne': ('exclude','%s__iexact',identity),
                  'lt': ('filter', '%s__lt',identity),
                  'le': ('filter', '%s__lte',identity),
                  'gt': ('filter', '%s__gt',identity),
                  'ge': ('filter', '%s__gte',identity),
                  'bw': ('filter', '%s__istartswith',identity),
                  'bn': ('exclude','%s__istartswith',identity),
                  'in': ('filter', '%s__in', f_list),
                  'ni': ('exclude','%s__in', f_list),
                  'ew': ('filter', '%s__iendswith',identity),
                  'en': ('exclude','%s__iendswith', identity),
                  'cn': ('filter', '%s__icontains', identity),
                  'nc': ('exclude','%s__icontains', identity)
                  }
        if op in django_equivalences:
            tipo, filtro, f = django_equivalences[op]
        else:
            tipo, filtro, f = django_equivalences['eq']
        filtro = str(filtro % field)
        query = {filtro:f(value)}

        return tipo, query

    @property
    def actual_page(self):
        "Gets the actual page"
        return int(self.request.GET.get('page','1'))


    @property
    def actual_num_rows(self):
        "Gets the actual numbre of rows defined"
        return int(self.request.GET.get('rows',self.num_rows))

    @property
    def order(self):
        "Gets the actual sort order"
        sidx = self.request.GET.get('sidx','id')
        sord = '' if self.request.GET.get('sord','asc')=='asc' else '-'
        orden = '%s%s' % (sord,sidx)
        return orden

    @property
    def is_search(self):
        "Returns true is the parameter _search is set"
        return self.request.GET.get('_search') == 'true'

    def get_response(self):
        "Returns the json response. You must override get_rows"
        record_list = self.query
        if self.is_search:
            searchField = self.request.GET.get('searchField')
            searchOp = self.request.GET.get('searchOper')
            tipo, query = self.jqfilter(searchOp, searchField,self.request.GET.get('searchString'))
            record_list = record_list.filter(**query) if tipo == 'filter' else  record_list.exclude(**query)
        record_list = record_list.order_by(self.order)
        paginator = Paginator(record_list, self.actual_num_rows)
        try:
            datos = paginator.page(self.actual_page)
        except (EmptyPage, InvalidPage):
            datos = paginator.page(paginator.num_pages)
        rta ={}
        rta['total'] = paginator.num_pages
        rta['page'] = self.actual_page
        rta['records'] =paginator.count 
        rta['rows'] = self.get_rows(datos.object_list)
        rta['cell'] = 'cell'
        return rta

    def get_rows(self, object_list):
        """return [{'id':obj.id, obj.description} for obj in object_list]"""
        return list()
